package cn.edu.swu.cly.miniwebsvr.handler;

import cn.edu.swu.cly.miniwebsvr.core.Config;
import cn.edu.swu.cly.miniwebsvr.core.Handler;
import cn.edu.swu.cly.miniwebsvr.core.Parameter;

import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.Files;

public class DefaultHandler implements Handler {

    @Override
    public void handle(Parameter request, OutputStream response) {
        // TODO: 222024321072039/蔡礼洋
        // 1. 获取请求路径（可能需要将 / 映射到 index.html）
        String requestUrl = request.getUrl(); // 获取原始请求路径
        String targetFile = requestUrl.equals("/") ? "index.html" : requestUrl.substring(1);

        // 2. 根据 Config.getWebRoot() 构建完整文件路径
        Config config = Config.getInstance();
        String webRoot = config.getWebRoot();
        Path filePath = Paths.get(Config.getInstance().getWebRoot(), request.getUrl().equals("/") ? "index.html" : request.getUrl().substring(1));

        try {
            if (Files.exists(filePath) && !Files.isDirectory(filePath)) {
                byte[] fileBytes = Files.readAllBytes(filePath);

                // TODO: 222024321072039/蔡礼洋 确定并设置正确的 Content-Type (例如 text/html, image/jpeg 等)
                String contentType;
                //探测文件类型（基于文件扩展名）
                String probeType = Files.probeContentType(filePath);
                if (probeType != null) {
                    contentType = probeType;
                } else {
                    //手动补充常见类型的判断（如果自动探测失败）
                    if (targetFile.endsWith(".html") || targetFile.endsWith(".htm")) {
                        contentType = "text/html; charset=UTF-8";
                    } else if (targetFile.endsWith(".css")) {
                        contentType = "text/css";
                    } else if (targetFile.endsWith(".js")) {
                        contentType = "application/javascript";
                    } else if (targetFile.endsWith(".jpg") || targetFile.endsWith(".jpeg")) {
                        contentType = "image/jpeg";
                    } else if (targetFile.endsWith(".png")) {
                        contentType = "image/png";
                    } else {
                        contentType = "application/octet-stream"; //未知类型默认二进制流
                    }
                }

                // 写入 200 OK 响应头
                response.write(("HTTP/1.1 200 OK\r\n").getBytes());
                response.write(("Content-Type: " + contentType + "\r\n").getBytes());
                response.write(("Content-Length: " + fileBytes.length + "\r\n").getBytes());
                response.write(("\r\n").getBytes());

                // 写入文件内容
                response.write(fileBytes);
            } else {
                // 文件不存在或路径错误，返回 404
                String content = "<h1>404 Not Found</h1><p>The requested resource " + request.getUrl() + " was not found.</p>";
                response.write(("HTTP/1.1 404 Not Found\r\n").getBytes());
                response.write(("Content-Type: text/html; charset=UTF-8\r\n").getBytes());
                response.write(("Content-Length: " + content.getBytes().length + "\r\n").getBytes());
                response.write(("\r\n").getBytes());
                response.write(content.getBytes());
            }
        } catch (IOException e) {
            // TODO: 222024321072039/蔡礼洋 文件读取异常，返回 500 Internal Server Error
            try {
                String errorContent = "<h1>500 Internal Server Error</h1><p>Failed to process the request.</p>";
                byte[] errorBytes = errorContent.getBytes(StandardCharsets.UTF_8);
                response.write(("HTTP/1.1 500 Internal Server Error\r\n").getBytes(StandardCharsets.UTF_8));
                response.write(("Content-Type: text/html; charset=UTF-8\r\n").getBytes(StandardCharsets.UTF_8));
                response.write(("Content-Length: " + errorBytes.length + "\r\n").getBytes(StandardCharsets.UTF_8));
                response.write(("\r\n").getBytes(StandardCharsets.UTF_8));
                response.write(errorBytes);
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        } finally {
            try {
                response.flush();
            } catch (IOException e) { /* ignore */ }
        }
    }
}
